package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: Administrator
 * \* Date: 2022/8/1
 * \* Time: 19:16
 * \* To change this template use File | Settings | File Templates.
 * \* Description:
 * \
 */

@Aspect //表示此类是一个切面
@Component
public class UserAspect {

    /**
     * 定义pointcut 切点的前置通知
     * 在执行目标方法之前执行的方法就叫做前置前置通知
     */
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("前置通知:被执行了。");
    }

    //定义切点，这里使用AspectJ表达式
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut(){

    }

    /**
     * 针对pointcut切点的后置通知
     */
    @After("pointcut()")
    public void doAfter(){
        System.out.println("后置通知：被执行了");
    }

    @AfterReturning("pointcut()")
    public void doAfterReturning(){
        System.out.println("执行了AfterReturning方法");
    }

    @AfterThrowing("pointcut()")
    public void doAfterThrowing(){
        System.out.println("执行了AfterThrowing方法");

    }

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint){
        //spring中时间统计对象
        StopWatch stopWatch = new StopWatch();
        Object obj = null;
      //  System.out.println("Around 方法开始执行");
        try {
            stopWatch.start();//开始计时
            obj = joinPoint.proceed();
            stopWatch.stop();//停止计时
        } catch (Throwable e) {
            e.printStackTrace();
        }
        //System.out.println("Around 方法结束执行");
        System.out.println(joinPoint.getSignature().getDeclaringTypeName()+"."+
                joinPoint.getSignature().getName()+"方法执行花费的时间："+
                stopWatch.getTotalTimeMillis()+"ms");
        return obj;
    }
}
